package io.xxx.omni.sync.impl

import com.alibaba.fastjson.JSONObject
import io.xxx.omni.sync.Document
import io.xxx.omni.sync.PagePorter
import io.xxx.omni.sync.Store
import io.xxx.omni.util.dateTimeFormatter
import io.xxx.omni.util.offset
import io.xxx.omni.util.sign
import io.xxx.omni.util.toLocalDateTime
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
import org.springframework.web.util.UriComponentsBuilder
import java.time.LocalDateTime
import java.util.*

abstract class WwXxPagePorter : PagePorter() {

    private val httpUrl = "http://mapi.bbtkids.cn/1.0/popapi/router"

    override val platformCode = "beibei"

    protected abstract val method: String

    protected fun getResponse(
        store: Store,
        params: Map<String, String> = emptyMap()
    ): JSONObject {
        val signMap = TreeMap(params)
        signMap["method"] = method
        signMap["timestamp"] = LocalDateTime.now().toEpochSecond(offset).toString()
        signMap["appid"] = store.appKey!!
        signMap["appsecret"] = store.appSecret!!
        signMap["sign"] = sign(store.appSecret!!, signMap)
        val urlBuilder = UriComponentsBuilder.fromHttpUrl(httpUrl)
        signMap.forEach { if (it.key != "appsecret") urlBuilder.queryParam(it.key, it.value) }
        val response = restTemplate.getForEntity(urlBuilder.toUriString(), JSONObject::class.java)
        if (response.statusCode.isError || response.body == null) {
            val msg = "接口[method: $method, queryParams: $signMap]异常"
            throw RuntimeException(msg)
        }
        val body = response.body!!
        if (!body.getBoolean("success")) {
            val msg = "接口[method: $method, queryParams: $signMap]异常: $body"
            log.error(msg)
            throwException(method, body.getString("err_code"), body.getString("err_msg"))
        }
        return response.body!!.getJSONObject("data")
    }

    protected fun getParams(
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        timeRange: String,
        pageNo: Long = 1
    ): Map<String, String> {
        return mapOf(
            "time_range" to timeRange,
            "start_time" to startTime.format(dateTimeFormatter),
            "end_time" to endTime.format(dateTimeFormatter),
            "page_no" to pageNo.toString(),
            "page_size" to pageSize.toString(),
        )
    }

    companion object {
        private val log = LoggerFactory.getLogger(WwXxPagePorter::class.java)
    }
}

@Component
class WwXxTradePorter : WwXxPagePorter() {

    override val method = "bbt.outer.trade.order.get"

    override val jobId = 1

    override fun getParameters(store: Store): List<Any> {
        return listOf("modified_time")
    }

    override fun getCount(store: Store, startTime: LocalDateTime, endTime: LocalDateTime, parameter: Any?): Long? {
        val params = getParams(startTime, endTime, parameter as String)
        val response = getResponse(store, params)
        return response.getLong("count")
    }

    override fun getData(
        store: Store,
        startTime: LocalDateTime,
        endTime: LocalDateTime,
        parameter: Any?,
        pageNo: Long,
    ): List<Document>? {
        val params = getParams(startTime, endTime, parameter as String, pageNo)
        val response = getResponse(store, params)
        return response.getJSONArray("orders")?.map {
            @Suppress("unchecked_cast")
            val value = JSONObject(it as Map<String, Any>)
            Document(
                value.getString("oid"),
                value,
                value.getString("modified_time").toLocalDateTime()
            )
        }
    }
}